package com.jingfu.configuration.shiro;

import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.DefaultPasswordService;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.shiro.cache.MapCache;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.mgt.SessionsSecurityManager;
import org.apache.shiro.spring.config.ShiroAnnotationProcessorConfiguration;
import org.apache.shiro.spring.config.ShiroBeanConfiguration;
import org.apache.shiro.spring.web.config.*;
import org.apache.shiro.util.SoftHashMap;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * spring web 应用的shiro集成，单个应用绝大部分使用默认配置即可，即基于servlet容器的SessionManager，
 * session有效时间，过期策略、持久化均交由servlet容器管理
 * @author jingfuu@163.com
 * @version v1.0
 * @date 2022/1/6 下午6:20
 **/
@Configuration
@Import({ShiroBeanConfiguration.class,
        ShiroAnnotationProcessorConfiguration.class,
        ShiroWebConfiguration.class,
        ShiroWebFilterConfiguration.class,
        //ShiroRequestMappingConfig.class, //必须在servlet容器上下文中配置,因为无法获取子容器中的RequestMappingHandlerMapping
        MyConfiguration.class})
public class ShiroWebConfig {
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition filterChainDefinition = new DefaultShiroFilterChainDefinition();
        filterChainDefinition.addPathDefinition("/favicon.ico","anon");
        filterChainDefinition.addPathDefinition("/admin/**","anon");
        filterChainDefinition.addPathDefinition("/component/**","anon");
        //common下所有接口放行
        filterChainDefinition.addPathDefinition("/common/**","anon");
        //验证码过滤器，在登录前首先校验验证码
        filterChainDefinition.addPathDefinition("/user/login","verifyCodeFilter,userAuthc");
        //filterChainDefinition.addPathDefinition("/login.jsp","anon");

        //登出过滤器
        filterChainDefinition.addPathDefinition("/user/logout","logout");


        filterChainDefinition.addPathDefinition("/**","userAuthc");
        return filterChainDefinition;
    }

    @Bean
    public CredentialsMatcher credentialsMatcher() {
        PasswordMatcher passwordMatcher = new PasswordMatcher();
        PasswordService passwordService = passwordService();
        passwordMatcher.setPasswordService(passwordService);
        return passwordMatcher;
    }

    /**
     * 使用PasswordService可以提供加解密密码服务
     * @return
     */
    @Bean
    public PasswordService passwordService(){
        DefaultPasswordService passwordService = new DefaultPasswordService();
        //HashService设置，使用默认的DefaultHashService，在此修改hash算法，迭代次数等
        ((DefaultHashService) passwordService.getHashService()).setHashIterations(15);
        return passwordService;
    }

    //相当于调用SecurityUtils.setSecurityManager(securityManager)
    @Bean
    public MethodInvokingFactoryBean methodInvokingFactoryBean(SessionsSecurityManager securityManager){
        MethodInvokingFactoryBean methodInvokingFactoryBean = new MethodInvokingFactoryBean();
        methodInvokingFactoryBean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
        methodInvokingFactoryBean.setArguments(securityManager);
        return methodInvokingFactoryBean;
    }
}
